package diplomovka.graphCreator;

import java.io.File;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.bcel.classfile.JavaClass;
import org.apache.bcel.classfile.LocalVariable;
import org.jdom.Element;

import diplomovka.graphCreator.modelParts.MAnnotation;
import diplomovka.graphCreator.modelParts.MException;
import diplomovka.graphCreator.modelParts.MMethod;
import diplomovka.graphCreator.modelParts.Type;

public class AnnotationCreator implements ModelPartCreator {

	@Override
	public boolean canHandle(Class loadedClass) {
		return loadedClass.isAnnotation();
	}

	@Override
	public Type createModelPart(Class loadedClass, JavaClass loadedByteCodes, Map<String, Element> configFiles) {
		MAnnotation mAnnotation = new MAnnotation();
		
		//set name
		String name = loadedClass.getName();
		mAnnotation.setName(name);
		
		//set type
		Class type = loadedClass.getClass();
		mAnnotation.setType(type);
		
		//load methods
		Method[] methods = loadedClass.getDeclaredMethods();
		for (Method method : methods) {
			List<String> parameterNames = new ArrayList<String>();
			org.apache.bcel.classfile.Method methodByteCode = loadedByteCodes.getMethod(method);
			LocalVariable[] lv = methodByteCode.getLocalVariableTable().getLocalVariableTable();
			for (LocalVariable localVariable : lv) {
				String parameterName = localVariable.getName();
				parameterNames.add(parameterName);
			}
			
			MMethod mMethod = new MMethod();
			
			String methodName = method.getName();
			mMethod.setName(methodName);			
			
			Class[] exceptions = method.getExceptionTypes();
			for (Class exception : exceptions) {
				MException mException = new MException();
				mException.setName(exception.getName());
				mMethod.addException(mException);
			}
			
			int modifiers = method.getModifiers();
			mMethod.setModifiers(modifiers);
			
			Class[] parameters = method.getParameterTypes();
			int index = 0; 
			for (Class parameter : parameters) {
				String parameterName = parameterNames.get(index++);
				mMethod.addParameter(parameterName, parameter);
			}
			
			Class returnType = method.getReturnType();
			mMethod.setReturnType(returnType);
			
			Object defaultValue = method.getDefaultValue();
			mMethod.setDefaultValue(defaultValue);
			
			mAnnotation.addMethod(mMethod);
		}
		
		//set modifiers
		int modifiers = loadedClass.getModifiers();
		mAnnotation.setModifiers(modifiers);
		
		return mAnnotation;
	}

}
